﻿#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <limits>

using namespace std;

// 学生成绩结构体
struct StudentGrade {
    string name;
    string student_id;
    string course;
    double score;
};

// 全局变量存储学生成绩
vector<StudentGrade> grades;

// 函数声明
void displayMenu();
void recordGrade();
void queryGrades();
void analyzeGrades();
void saveToFile();
void loadFromFile();
bool isDuplicate(const string& student_id, const string& course);
void clearInputBuffer();

int main() {
    // 从文件加载已有数据
    loadFromFile();

    int choice;
    do {
        displayMenu();
        cout << "请输入选项序号: ";
        cin >> choice;
        clearInputBuffer(); // 清除输入缓冲区

        switch (choice) {
        case 1:
            recordGrade();
            break;
        case 2:
            queryGrades();
            break;
        case 3:
            analyzeGrades();
            break;
        case 4:
            cout << "\n感谢使用学生成绩管理系统，再见！" << endl;
            // 退出前保存数据
            saveToFile();
            return 0;
        default:
            cout << "无效的选项，请重新输入！" << endl;
        }
    } while (true);

    return 0;
}

// 显示主菜单
void displayMenu() {
    cout << "\n=================================" << endl;
    cout << "欢迎使用学生成绩管理系统" << endl;
    cout << "=================================" << endl;
    cout << "请选择操作：" << endl;
    cout << "1. 记录学生成绩" << endl;
    cout << "2. 查询学生成绩" << endl;
    cout << "3. 统计课程成绩" << endl;
    cout << "4. 退出系统" << endl;
    cout << "=================================" << endl;
}

// 记录学生成绩
void recordGrade() {
    StudentGrade newGrade;

    cout << "\n===== 记录学生成绩 =====" << endl;
    cout << "请输入学生姓名: ";
    getline(cin, newGrade.name);

    cout << "请输入学生学号: ";
    getline(cin, newGrade.student_id);

    cout << "请输入课程名称: ";
    getline(cin, newGrade.course);

    // 检查同一课程中是否已存在该学号
    if (isDuplicate(newGrade.student_id, newGrade.course)) {
        cout << "错误：该学号在此课程中已存在记录！" << endl;
        return;
    }

    // 获取并验证成绩输入
    while (true) {
        cout << "请输入成绩（0-100）: ";
        if (cin >> newGrade.score) {
            if (newGrade.score >= 0 && newGrade.score <= 100) {
                clearInputBuffer(); // 清除输入缓冲区
                break;
            }
            cout << "错误：成绩必须在0-100之间！" << endl;
        }
        else {
            cout << "错误：请输入有效的数字！" << endl;
            cin.clear();
        }
        clearInputBuffer(); // 清除输入缓冲区
    }

    // 添加新记录
    grades.push_back(newGrade);
    cout << "成绩已成功记录！" << endl;

    // 保存到文件
    saveToFile();
}

// 查询学生成绩
void queryGrades() {
    if (grades.empty()) {
        cout << "当前没有成绩记录！" << endl;
        return;
    }

    cout << "\n===== 查询学生成绩 =====" << endl;
    cout << "请选择查询方式：" << endl;
    cout << "1. 按学生姓名查询" << endl;
    cout << "2. 按学生学号查询" << endl;
    cout << "3. 按课程名称查询" << endl;

    int choice;
    cout << "请输入选项序号: ";
    cin >> choice;
    clearInputBuffer(); // 清除输入缓冲区

    vector<StudentGrade> results;
    string searchTerm;

    switch (choice) {
    case 1:
        cout << "请输入学生姓名: ";
        getline(cin, searchTerm);
        for (const auto& grade : grades) {
            if (grade.name == searchTerm) {
                results.push_back(grade);
            }
        }
        break;
    case 2:
        cout << "请输入学生学号: ";
        getline(cin, searchTerm);
        for (const auto& grade : grades) {
            if (grade.student_id == searchTerm) {
                results.push_back(grade);
            }
        }
        break;
    case 3:
        cout << "请输入课程名称: ";
        getline(cin, searchTerm);
        for (const auto& grade : grades) {
            if (grade.course == searchTerm) {
                results.push_back(grade);
            }
        }
        break;
    default:
        cout << "无效的选项！" << endl;
        return;
    }

    if (results.empty()) {
        cout << "没有找到匹配的记录！" << endl;
        return;
    }

    cout << "\n查询结果：" << endl;
    for (const auto& grade : results) {
        cout << "姓名: " << grade.name
            << ", 学号: " << grade.student_id
            << ", 课程: " << grade.course
            << ", 成绩: " << fixed << setprecision(1) << grade.score << endl;
    }
}

// 统计课程成绩
void analyzeGrades() {
    if (grades.empty()) {
        cout << "当前没有成绩记录！" << endl;
        return;
    }

    cout << "\n===== 统计课程成绩 =====" << endl;
    string course;
    cout << "请输入课程名称: ";
    getline(cin, course);

    vector<double> courseScores;
    for (const auto& grade : grades) {
        if (grade.course == course) {
            courseScores.push_back(grade.score);
        }
    }

    if (courseScores.empty()) {
        cout << "该课程没有成绩记录！" << endl;
        return;
    }

    double total = 0;
    double maxScore = courseScores[0];
    double minScore = courseScores[0];

    for (double score : courseScores) {
        total += score;
        if (score > maxScore) maxScore = score;
        if (score < minScore) minScore = score;
    }

    double average = total / courseScores.size();

    cout << "\n课程: " << course << endl;
    cout << "平均分: " << fixed << setprecision(2) << average << endl;
    cout << "最高分: " << fixed << setprecision(1) << maxScore << endl;
    cout << "最低分: " << fixed << setprecision(1) << minScore << endl;
}

// 保存数据到文件
void saveToFile() {
    ofstream outFile("grades.dat");
    if (!outFile) {
        cerr << "无法保存数据到文件！" << endl;
        return;
    }

    for (const auto& grade : grades) {
        outFile << grade.name << ","
            << grade.student_id << ","
            << grade.course << ","
            << grade.score << "\n";
    }

    outFile.close();
}

// 从文件加载数据
void loadFromFile() {
    ifstream inFile("grades.dat");
    if (!inFile) {
        // 文件不存在，无需加载
        return;
    }

    string line;
    while (getline(inFile, line)) {
        stringstream ss(line);
        string token;
        StudentGrade grade;

        // 解析姓名
        getline(ss, token, ',');
        grade.name = token;

        // 解析学号
        getline(ss, token, ',');
        grade.student_id = token;

        // 解析课程
        getline(ss, token, ',');
        grade.course = token;

        // 解析成绩
        getline(ss, token, ',');
        try {
            grade.score = stod(token);
        }
        catch (...) {
            continue; // 跳过无效行
        }

        grades.push_back(grade);
    }

    inFile.close();
}

// 检查同一课程中是否有重复学号
bool isDuplicate(const string& student_id, const string& course) {
    for (const auto& grade : grades) {
        if (grade.student_id == student_id && grade.course == course) {
            return true;
        }
    }
    return false;
}

// 清除输入缓冲区
void clearInputBuffer() {
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
}